package org.airmvc
{
	import flash.utils.Dictionary;
	import flash.utils.getDefinitionByName;
	import morn.core.handlers.Handler;
	
	/**
	 * 模块管理器
	 * @author WLDragon
	 */
	public class ModulesManager
	{
		/**
		 * 通过配置初始化模块地图
		 * @param	config        配置文件（如果是加载模式，使用ModulesConfig.xml，否则使用ModulesConfig.as）
		 * @param	isLoadMode    是否为加载模式
		 */
		static public function init(config:*, isLoadMode:Boolean = true):void
		{
			var firstDefine:String;
			if (isLoadMode)
			{
				for each (var x:XML in config.modules.module)
				{
					add(x.@def, isLoadMode, x.@url);
				}
				firstDefine = config.firstModule[0].@def;
			}
			else
			{
				for each (var o:Object in config.modules)
				{
					add(o.def, isLoadMode);
				}
				firstDefine = config.firstModule;
			}
			
			//启动第一个入口模块
			dispatch.broadcast(firstDefine, [firstDefine]);
			config = null;
		}
		
		/**
		 * 添加模块信息到模块地图,一般在ModulesConfig文件中配置,也可直接在工程中通过此方法动态增加
		 * @param	definition 模块控制类的定义名
		 * @param	url    模块加载路径
		 */
		static public function add(definition:String, mode:Boolean, url:String = null):void
		{
			moduleMap[definition] = new Info(definition, mode, url);
			dispatch.interest(definition, loadModule);
		}
		
		/**
		 * 移除模块
		 * ::移除模块应该还要考虑移除对view的引用和向其他模块发送的事件::Mark
		 * @param	definition 模块控制类的定义名
		 */
		static public function remove(definition:String):void
		{
			var info:Info = moduleMap[definition] as Info;
			info.module = null;
			moduleMap[definition] = null;
			delete moduleMap[definition];
		}
		
		/**
		 * 加载模块
		 * @param	args 参数列表
		 */
		static private function loadModule(... args):void
		{
			var definition:String = args[0];
			var info:Info = moduleMap[definition] as Info;
			info.args = args;
			if (info.isLoadMode)
				App.loader.loadSWF(info.url, new Handler(onComplete, [info]));
			else
				onComplete(info);
		}
		
		/**
		 * 模块加载完成后的回调函数
		 * @param	info 模块信息
		 */
		static private function onComplete(... args):void
		{
			var info:Info = args[0] as Info;
			var c:Class = getDefinitionByName(info.definition) as Class;
			info.module = ((new c) as Controller);
			info.module.start(info.definition, info.args);
			dispatch.cancelInterest(info.definition, loadModule);
		}
		
		/**保存模块的信息和对模块实例的引用（避免系统回收）*/
		static private var moduleMap:Dictionary = new Dictionary();
		/**消息分派器*/
		static internal const dispatch:Dispatcher = new Dispatcher();
	}

}

import org.airmvc.Controller;

/**
 * 模块信息
 */
class Info
{
	public function Info(definition:String, mode:Boolean, url:String)
	{
		this.definition = definition;
		this.isLoadMode = mode;
		this.url = url;
	}
	
	/**模块的控制类定义*/
	public var definition:String;
	/**模块加载路径*/
	public var url:String;
	/**模块控制类引用，防止垃圾回收::Mark::考虑要不要把Info实例删掉换其他数组引用*/
	public var module:Controller;
	/**启动时需要的参数*/
	public var args:Array;
	/**是否为加载模式*/
	public var isLoadMode:Boolean;
}